Understanding UIKit and the iOS View Hierarchy
Course: iOS App Development Training
Topic: Understanding UIKit and the iOS View Hierarchy
Course Link: iOS App Development Training at JustAcademy
Demo Link: Register for a Course Demo
Official Website: JustAcademy
1. Introduction to UIKit
UIKit is Apple's framework for building user interfaces in iOS applications. It provides components and tools for creating screens, displaying information, handling touch interactions, managing navigation, presenting alerts, and responding to device-related events.
UIKit includes ready-to-use interface components such as labels, buttons, text fields, image views, scroll views, tables, collection views, navigation controllers, and tab bar controllers. Developers can combine these components to build interactive mobile applications without implementing every interface element from scratch.
UIKit is commonly used with the Swift programming language. Developers can create interfaces visually using Storyboards and Interface Builder or build them programmatically in Swift. UIKit can also work alongside SwiftUI in applications that need to combine declarative and traditional interface approaches.
Key Responsibilities of UIKit
- Creating and managing application interface elements.
- Organizing views into parent-child relationships.
- Managing screen layout and adapting to different device sizes.
- Handling user input, touch events, and gesture recognition.
- Supporting animations and visual transitions.
- Managing view controllers and screen presentation.
- Integrating with system features such as keyboards, alerts, and accessibility.
2. What Is a UIView?
UIView is the fundamental building block of UIKit interfaces. A view represents a rectangular region that can display content and respond to user interaction. It can contain other views, allowing developers to create complex interfaces from smaller components.
For example, a login screen may contain a parent view with a title label, email text field, password text field, login button, and an image view. Each component is a separate view that participates in the overall interface hierarchy.
Common UIView Properties
| Property |
Purpose |
Example |
frame |
Defines a view's position and size in its superview's coordinate system. |
view.frame |
bounds |
Defines the view's internal coordinate rectangle. |
view.bounds |
center |
Defines the center point of the view's frame. |
view.center |
backgroundColor |
Sets the view's background color. |
view.backgroundColor = .white |
alpha |
Controls the view's transparency. |
view.alpha = 0.5 |
isHidden |
Determines whether the view is hidden. |
view.isHidden = true |
clipsToBounds |
Controls whether content extending outside the view's bounds is clipped. |
view.clipsToBounds = true |
isUserInteractionEnabled |
Controls whether the view accepts user interaction. |
view.isUserInteractionEnabled = true |
3. What Is the iOS View Hierarchy?
The view hierarchy is a tree-like structure that organizes the views displayed on an iOS screen. A parent view can contain multiple child views, and each child view has one direct superview at a time. This structure determines how views are grouped, positioned, drawn, and involved in touch handling.
Consider a profile screen containing a background view, a profile image, a name label, and an edit button. The main content view may act as the parent, while the image, label, and button are its subviews.
Example View Hierarchy
UIWindow
|
+-- Root UIViewController's View
|
+-- Header UIView
| |
| +-- UIImageView
| +-- UILabel
|
+-- Content UIView
| |
| +-- UITextField
| +-- UIButton
|
+-- Footer UIView
|
+-- UILabel
This hierarchy shows how a screen can be divided into logical sections. The exact hierarchy of a real application may include additional system-managed views, containers, and intermediate layout views.
4. Superview and Subview Relationships
UIKit uses the terms superview and subview to describe parent-child relationships between views.
- Superview: The immediate parent view that contains another view.
- Subview: A view contained inside another view.
- Sibling views: Views that share the same immediate superview.
- Root view: The top-level view managed by a view controller for a screen or scene.
A view can contain many subviews, but it has only one direct superview at a time. A view without a superview may not be attached to the visible interface.
4.1 Adding a Subview
The addSubview(_:) method adds a child view to a parent view.
import UIKit
class ProfileViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let titleLabel = UILabel()
titleLabel.text = "My Profile"
titleLabel.textAlignment = .center
titleLabel.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(titleLabel)
NSLayoutConstraint.activate([
titleLabel.topAnchor.constraint(
equalTo: view.safeAreaLayoutGuide.topAnchor,
constant: 20
),
titleLabel.centerXAnchor.constraint(
equalTo: view.centerXAnchor
)
])
}
}
In this example, the label becomes a subview of the view controller's root view. Auto Layout constraints determine its position relative to the safe area and the horizontal center of the parent view.
4.2 Removing a Subview
The removeFromSuperview() method removes a view from its parent and detaches it from that part of the view hierarchy.
let messageLabel = UILabel()
messageLabel.text = "Welcome!"
view.addSubview(messageLabel)
// Remove the label when it is no longer needed.
messageLabel.removeFromSuperview()
Removing a view from its superview does not automatically mean that the object is immediately deallocated. Its lifetime also depends on other strong references.
5. Managing View Order and Overlapping Elements
Sibling views can overlap. Their ordering affects which view appears in front when they occupy the same screen area. By default, adding a subview places it above the existing sibling views in the parent's subview order.
Important View-Ordering Methods
| Method |
Purpose |
addSubview(_:) |
Adds a view as a child, normally placing it above existing siblings. |
bringSubviewToFront(_:) |
Moves a sibling view to the front of its parent's subview order. |
sendSubviewToBack(_:) |
Moves a sibling view behind the other subviews. |
insertSubview(_:aboveSubview:) |
Inserts a view above a specified sibling. |
insertSubview(_:belowSubview:) |
Inserts a view below a specified sibling. |
5.1 Example: Bringing a View to the Front
let backgroundView = UIView()
backgroundView.backgroundColor = .lightGray
let messageView = UIView()
messageView.backgroundColor = .systemBlue
view.addSubview(backgroundView)
view.addSubview(messageView)
// Ensure the message view appears above its sibling.
view.bringSubviewToFront(messageView)
View ordering is useful for badges, floating buttons, pop-up panels, overlays, and other interface elements that need to appear above surrounding content.
6. Understanding Frame and Bounds
The frame and bounds properties describe different aspects of a view's geometry. Understanding the difference is important when positioning views, building custom layouts, or working with transformations.
6.1 Frame
The frame describes the view's position and size in the coordinate system of its superview. It is commonly used to understand where a view is located relative to its parent.
let box = UIView(
frame: CGRect(x: 20, y: 50, width: 200, height: 100)
)
The example creates a view with an initial frame origin of (20, 50), a width of 200 points, and a height of 100 points. Its actual placement on screen depends on the parent view and any transformations.
6.2 Bounds
The bounds rectangle describes the view's internal coordinate system and size. It is particularly useful when drawing custom content inside a view. A view's bounds origin is often (0, 0), but it can differ in some scenarios.
print("Frame:", box.frame)
print("Bounds:", box.bounds)
Frame Versus Bounds
| Feature |
Frame |
Bounds |
| Coordinate system |
Superview's coordinate system |
The view's own coordinate system |
| Primary use |
Positioning and sizing relative to the parent |
Internal drawing and content coordinates |
| Origin |
Indicates the view's location in its parent |
Defines the origin of the view's internal coordinate space |
| Effect of transforms |
Can reflect the transformed bounding rectangle |
Defines the view's internal geometry |
7. Layout Management with Auto Layout
Auto Layout is UIKit's constraint-based layout system. Instead of manually assigning every view a fixed position, developers define relationships between views. UIKit calculates the appropriate layout based on the constraints and the current interface environment.
Auto Layout is useful because iOS applications must support different screen sizes, device orientations, dynamic text sizes, and other interface variations.
7.1 Common Constraint Relationships
- Top and bottom: Position a view vertically relative to another view or layout guide.
- Leading and trailing: Define horizontal relationships that adapt to the interface's reading direction.
- Width and height: Specify dimensions or relationships between dimensions.
- Center X and Center Y: Align a view around another view's center.
- Spacing: Define the distance between related views.
7.2 Example: Creating a Centered Button
import UIKit
class WelcomeViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let button = UIButton(type: .system)
button.setTitle("Get Started", for: .normal)
button.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(button)
NSLayoutConstraint.activate([
button.centerXAnchor.constraint(
equalTo: view.centerXAnchor
),
button.centerYAnchor.constraint(
equalTo: view.centerYAnchor
),
button.widthAnchor.constraint(
equalToConstant: 180
),
button.heightAnchor.constraint(
equalToConstant: 50
)
])
}
}
The button is centered within the root view and given explicit dimensions. For production interfaces, consider content-driven sizing and accessibility needs rather than relying exclusively on fixed dimensions.
8. Safe Area and Layout Guides
The safe area identifies the portion of a view that is not obscured by certain system interface elements, such as the status bar, device-specific display areas, or navigation and tab bars managed by containers. It helps developers position content where it remains comfortably visible.
UIKit provides safeAreaLayoutGuide for creating constraints relative to this region.
NSLayoutConstraint.activate([
titleLabel.topAnchor.constraint(
equalTo: view.safeAreaLayoutGuide.topAnchor,
constant: 16
),
titleLabel.leadingAnchor.constraint(
equalTo: view.safeAreaLayoutGuide.leadingAnchor,
constant: 20
),
titleLabel.trailingAnchor.constraint(
equalTo: view.safeAreaLayoutGuide.trailingAnchor,
constant: -20
)
])
This approach helps keep the title within the safe area while maintaining consistent spacing on supported devices. Scroll views, full-screen content, and intentionally edge-to-edge designs may require different layout decisions.
9. Common UIKit View Components
| Component |
Purpose |
Typical Use |
UILabel |
Displays text. |
Titles, descriptions, status messages. |
UIButton |
Responds to button actions. |
Submitting forms, navigation actions. |
UITextField |
Accepts single-line text input. |
Email fields, search boxes. |
UITextView |
Displays or edits multiline text. |
Notes, descriptions, message entry. |
UIImageView |
Displays images. |
Avatars, icons, illustrations. |
UIScrollView |
Supports scrolling content. |
Long forms, image galleries. |
UITableView |
Displays data in a row-based list. |
Settings, contacts, transaction lists. |
UICollectionView |
Displays flexible grid or list layouts. |
Product catalogs, photo galleries. |
UIStackView |
Arranges views in a linear layout. |
Form fields and grouped controls. |
10. Understanding UIViewController
A UIViewController manages a screen or a portion of an application's interface. It coordinates the view hierarchy, responds to lifecycle events, and connects user interactions with application behavior.
Each view controller typically has a root view accessible through its view property. Child views are placed inside that root view, either through Storyboards or programmatically.
Common View Controller Lifecycle Methods
| Method |
Purpose |
viewDidLoad() |
Called after the view controller's view has been loaded into memory; useful for initial setup. |
viewWillAppear(_:) |
Called before the view is added to the visible interface. |
viewDidAppear(_:) |
Called after the view has appeared. |
viewWillDisappear(_:) |
Called before the view is removed from the visible interface. |
viewDidDisappear(_:) |
Called after the view has disappeared. |
Example View Controller
import UIKit
class HomeViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemBackground
setupTitle()
}
private func setupTitle() {
let titleLabel = UILabel()
titleLabel.text = "Welcome to iOS Development"
titleLabel.font = .boldSystemFont(ofSize: 22)
titleLabel.textAlignment = .center
titleLabel.numberOfLines = 0
titleLabel.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(titleLabel)
NSLayoutConstraint.activate([
titleLabel.centerXAnchor.constraint(
equalTo: view.centerXAnchor
),
titleLabel.centerYAnchor.constraint(
equalTo: view.centerYAnchor
),
titleLabel.leadingAnchor.constraint(
greaterThanOrEqualTo: view.leadingAnchor,
constant: 20
),
titleLabel.trailingAnchor.constraint(
lessThanOrEqualTo: view.trailingAnchor,
constant: -20
)
])
}
}
11. Handling User Interaction
UIKit views can receive touch events and support user interaction. Standard controls such as buttons provide convenient mechanisms for handling actions, while gesture recognizers allow developers to respond to taps, swipes, pinches, and other gestures.
11.1 Button Action Example
import UIKit
class ActionViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let button = UIButton(type: .system)
button.setTitle("Tap Me", for: .normal)
button.translatesAutoresizingMaskIntoConstraints = false
button.addTarget(
self,
action: #selector(buttonTapped),
for: .touchUpInside
)
view.addSubview(button)
NSLayoutConstraint.activate([
button.centerXAnchor.constraint(
equalTo: view.centerXAnchor
),
button.centerYAnchor.constraint(
equalTo: view.centerYAnchor
)
])
}
@objc private func buttonTapped() {
print("Button was tapped")
}
}
11.2 Adding a Tap Gesture
let cardView = UIView()
cardView.backgroundColor = .systemBlue
cardView.isUserInteractionEnabled = true
let tapGesture = UITapGestureRecognizer(
target: self,
action: #selector(handleCardTap)
)
cardView.addGestureRecognizer(tapGesture)
view.addSubview(cardView)
@objc private func handleCardTap() {
print("Card tapped")
}
In a view controller, the gesture handler should be declared within the class. If a view has multiple interactive controls, design gesture handling carefully so that gestures do not interfere with the expected behavior of buttons or other controls.
12. View Clipping, Visibility, and Transparency
UIKit offers several properties that affect how views appear and interact with their surroundings.
isHidden: Hides a view from display and prevents it from receiving normal interaction.
alpha: Changes the transparency of the view and its rendered contents.
clipsToBounds: Clips a view's subviews to the boundaries of its bounds when enabled.
isUserInteractionEnabled: Determines whether the view participates in user interaction.
backgroundColor: Sets the background appearance of a view.
Example
let card = UIView()
card.backgroundColor = .systemTeal
card.clipsToBounds = true
card.alpha = 1.0
// Hide the card when necessary.
card.isHidden = false
// Disable user interaction when the card should not accept input.
card.isUserInteractionEnabled = true
Changing alpha to zero makes a view invisible, but developers should not rely on alpha alone to communicate whether an element is interactive. Explicitly manage interaction and accessibility behavior for controls that are unavailable.
13. Drawing and Updating Views
UIKit manages view rendering and updates the display when needed. Most interface changes can be made by modifying properties such as text, color, image, or constraints. Custom drawing is useful when the standard components cannot produce the required visual output.
13.1 setNeedsDisplay()
The setNeedsDisplay() method marks a view as needing to redraw its custom content during a future drawing cycle. It does not force an immediate redraw.
class CircleView: UIView {
override func draw(_ rect: CGRect) {
guard let context = UIGraphicsGetCurrentContext() else {
return
}
context.setFillColor(UIColor.systemBlue.cgColor)
let circleRect = CGRect(
x: rect.midX - 40,
y: rect.midY - 40,
width: 80,
height: 80
)
context.fillEllipse(in: circleRect)
}
func refreshDrawing() {
setNeedsDisplay()
}
}
Custom drawing should be used only when necessary. For ordinary interface elements, standard UIKit views and controls are usually simpler, more accessible, and easier to maintain.
14. View Hierarchy and Touch Handling
UIKit uses the view hierarchy to determine which view should receive a touch. Hit-testing examines the relevant views and their coordinate spaces to identify the deepest eligible view containing the touch location.
Touch handling can be affected by the following factors:
- Whether the view is hidden.
- Whether the view's alpha is sufficiently visible for hit-testing.
- Whether user interaction is enabled.
- Whether the touch falls within the view's bounds and eligible subviews.
- Whether a gesture recognizer or another interactive component handles the event.
A frequent mistake is placing a transparent overlay above a button. Even when the overlay appears invisible, it may intercept touches if it participates in hit-testing. Review the hierarchy and interaction settings when a visible control does not respond as expected.
15. Performance and Best Practices
- Keep the view hierarchy organized and avoid unnecessary nested containers.
- Use Auto Layout for adaptable interfaces instead of hardcoding every position.
- Use stack views when they simplify groups of related controls.
- Prefer standard UIKit components over custom-drawn controls when possible.
- Reuse table-view cells and collection-view cells for large data sets.
- Keep UI changes on the main thread.
- Use clear constraints and meaningful names for maintainable code.
- Avoid repeatedly creating large view hierarchies when reusable components are suitable.
- Use Instruments and Xcode debugging tools to investigate rendering or layout performance problems.
- Test different screen sizes, orientations, text sizes, and accessibility settings.
16. Common Problems and Troubleshooting
| Problem |
Possible Cause |
Solution |
| A view is not visible. |
It was not added to the hierarchy, is hidden, or has an unexpected frame. |
Check the parent view, visibility properties, and layout constraints. |
| A button does not respond. |
Its action is not connected or another view intercepts touches. |
Verify the target-action connection, interaction settings, and view order. |
| Views overlap incorrectly. |
Sibling order or constraints are incorrect. |
Inspect the hierarchy and adjust constraints or subview ordering. |
| Layout breaks on smaller screens. |
Fixed coordinates or incomplete constraints. |
Use Auto Layout, safe-area guides, and adaptive sizing. |
| Text is cut off. |
Insufficient space, restrictive constraints, or unsupported text sizing. |
Allow multiline text, review compression resistance, and support Dynamic Type. |
| Auto Layout warnings appear. |
Conflicting, missing, or ambiguous constraints. |
Inspect Xcode's constraint logs and simplify the layout rules. |
| A custom view does not redraw. |
The display has not been invalidated after its drawing data changed. |
Call setNeedsDisplay() when the custom drawing needs updating. |
17. Practical Exercise: Create a Profile Card
Objective: Build a simple profile card using UIKit views and understand how the view hierarchy organizes its components.
Requirements
- Create a new iOS project in Xcode using UIKit and Swift.
- Create a parent card view inside the view controller's root view.
- Add an image view for the profile picture.
- Add a label for the person's name and another for a short description.
- Add an edit button and connect its action.
- Use Auto Layout constraints to arrange the components.
- Apply a background color and rounded corners to the card.
- Test the screen on different simulator sizes.
Sample Implementation
import UIKit
class ProfileCardViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemBackground
let cardView = UIView()
cardView.backgroundColor = .secondarySystemBackground
cardView.layer.cornerRadius = 16
cardView.translatesAutoresizingMaskIntoConstraints = false
let nameLabel = UILabel()
nameLabel.text = "Alex Morgan"
nameLabel.font = .boldSystemFont(ofSize: 22)
nameLabel.textAlignment = .center
nameLabel.translatesAutoresizingMaskIntoConstraints = false
let descriptionLabel = UILabel()
descriptionLabel.text = "iOS App Developer"
descriptionLabel.textAlignment = .center
descriptionLabel.textColor = .secondaryLabel
descriptionLabel.translatesAutoresizingMaskIntoConstraints = false
let editButton = UIButton(type: .system)
editButton.setTitle("Edit Profile", for: .normal)
editButton.translatesAutoresizingMaskIntoConstraints = false
editButton.addTarget(
self,
action: #selector(editProfile),
for: .touchUpInside
)
view.addSubview(cardView)
cardView.addSubview(nameLabel)
cardView.addSubview(descriptionLabel)
cardView.addSubview(editButton)
NSLayoutConstraint.activate([
cardView.centerXAnchor.constraint(
equalTo: view.centerXAnchor
),
cardView.centerYAnchor.constraint(
equalTo: view.centerYAnchor
),
cardView.leadingAnchor.constraint(
equalTo: view.safeAreaLayoutGuide.leadingAnchor,
constant: 24
),
cardView.trailingAnchor.constraint(
equalTo: view.safeAreaLayoutGuide.trailingAnchor,
constant: -24
),
nameLabel.topAnchor.constraint(
equalTo: cardView.topAnchor,
constant: 28
),
nameLabel.leadingAnchor.constraint(
equalTo: cardView.leadingAnchor,
constant: 16
),
nameLabel.trailingAnchor.constraint(
equalTo: cardView.trailingAnchor,
constant: -16
),
descriptionLabel.topAnchor.constraint(
equalTo: nameLabel.bottomAnchor,
constant: 8
),
descriptionLabel.leadingAnchor.constraint(
equalTo: cardView.leadingAnchor,
constant: 16
),
descriptionLabel.trailingAnchor.constraint(
equalTo: cardView.trailingAnchor,
constant: -16
),
editButton.topAnchor.constraint(
equalTo: descriptionLabel.bottomAnchor,
constant: 16
),
editButton.centerXAnchor.constraint(
equalTo: cardView.centerXAnchor
),
editButton.bottomAnchor.constraint(
equalTo: cardView.bottomAnchor,
constant: -20
)
])
}
@objc private func editProfile() {
print("Edit Profile tapped")
}
}
Expected result: A profile card appears centered on the screen with a name, role description, and edit button. The parent card contains three child views, demonstrating the parent-child relationship in the UIKit view hierarchy.
18. Interview Questions and Answers
Q1. What is UIKit?
Answer: UIKit is Apple's framework for building iOS user interfaces. It provides views, controls, view controllers, navigation components, and event-handling functionality.
Q2. What is UIView?
Answer: UIView is the base class for most UIKit interface elements. It manages a rectangular area, displays content, organizes subviews, and participates in event handling.
Q3. What is a view hierarchy?
Answer: A view hierarchy is a tree-like structure of parent and child views that organizes the interface and influences layout, drawing, and touch handling.
Q4. What is the difference between a superview and a subview?
Answer: A superview is the immediate parent that contains another view. A subview is a child contained inside that parent.
Q5. What is the difference between frame and bounds?
Answer: Frame describes a view's position and size in its superview's coordinate system, while bounds describes the view's own internal coordinate rectangle.
Q6. What does addSubview(_:) do?
Answer: It adds a view to another view's hierarchy, establishing a parent-child relationship.
Q7. What is Auto Layout?
Answer: Auto Layout is a constraint-based layout system that calculates view positions and dimensions based on relationships between interface elements.
Q8. What is the purpose of safeAreaLayoutGuide?
Answer: It provides a layout reference for positioning content within the view's safe area, helping avoid certain system interface obstructions.
Q9. How can you change the front-to-back order of views?
Answer: Methods such as bringSubviewToFront(_:), sendSubviewToBack(_:), and insertSubview(_:aboveSubview:) can change sibling ordering.
Q10. What is the role of UIViewController?
Answer: UIViewController manages a screen or interface section, coordinates its root view and related lifecycle events, and connects user interactions to application behavior.
Q11. Why might a button not receive a tap?
Answer: Its action may be incorrectly connected, interaction may be disabled, or another view or gesture recognizer may intercept the touch.
Q12. When should setNeedsDisplay() be used?
Answer: It should be used when a custom-drawn view needs its content redrawn. It schedules an update rather than forcing an immediate redraw.
19. Quick Revision Checklist
- Understand UIKit and its role in iOS development.
- Know the purpose of UIView and UIViewController.
- Understand the parent-child structure of the view hierarchy.
- Know how to add, remove, and reorder subviews.
- Differentiate between frame and bounds.
- Use Auto Layout and safe-area guides for adaptive layouts.
- Understand common UIKit controls and their purposes.
- Handle button actions and gesture recognizers.
- Know how visibility, transparency, and clipping affect views.
- Debug layout constraints and touch-handling issues in Xcode.
20. Official Learning Resources
21. Conclusion
UIKit provides the foundation for building interactive native iOS interfaces. Understanding UIView, UIViewController, and the view hierarchy helps developers organize screens, control visual ordering, manage user interactions, and create responsive layouts.
By mastering superview and subview relationships, frame and bounds, Auto Layout, safe-area guides, and event handling, developers can build interfaces that are easier to maintain and adapt to different devices. Practical exercises in Xcode help turn these concepts into useful skills for real-world iOS application development.
Explore more learning opportunities through JustAcademy, visit the iOS App Development Training Course, or register for a course demo.